home *** CD-ROM | disk | FTP | other *** search
/ Java Programmer's Toolkit / Java Programmer's Toolkit.iso / gs3.53 / pdf_font.ps < prev    next >
Text File  |  1996-01-10  |  12KB  |  375 lines

  1. %    Copyright (C) 1994, 1995 Aladdin Enterprises.  All rights reserved.
  2.  
  3. % pdf_font.ps
  4. % PDF font operations.
  5.  
  6. /.setlanguagelevel where { pop 2 .setlanguagelevel } if
  7. .currentglobal true .setglobal
  8. /pdfdict where { pop } { /pdfdict 100 dict def } ifelse
  9. GS_PDF_ProcSet begin
  10. pdfdict begin
  11.  
  12. % We cache the PostScript font in an additional element of the
  13. % font resource dictionary, called PSFont.
  14.  
  15. % ---------------- Encodings ---------------- %
  16.  
  17. % Apply a list of differences to an Encoding.
  18. /updateencoding        % <encoding> <differences> updateencoding <enc'>
  19.  { exch dup length array copy
  20.    exch dup 0 get exch dup length 1 sub
  21.    1 exch getinterval
  22.     { dup type /nametype ne
  23.        { exch pop }
  24.        { 3 copy put pop 1 add }
  25.       ifelse
  26.     }
  27.    forall pop
  28.  } bdef
  29.  
  30. % Get the Encoding for a font.
  31. /getencoding        % <base-encoding> <font-resource> getencoding <enc>
  32.  { /Encoding knownoget
  33.     { dup type /nametype eq
  34.        { exch pop findencoding
  35.        }
  36.        { dup /BaseEncoding knownoget
  37.       { findencoding 3 -1 roll pop exch
  38.       }
  39.      if
  40.      /Differences knownoget { updateencoding } if
  41.        }
  42.       ifelse
  43.     }
  44.    if
  45.  } bdef
  46.  
  47. % Insert a modified encoding into a font if needed.
  48. /adjustencoding        % <font-resource> <font> adjustencoding
  49.             %   <font-resource> <font'>
  50.  { 1 index /Encoding known
  51.     { dup /Encoding get 2 index getencoding
  52.       dup 2 index /Encoding get ne
  53.        {    % Insert the new Encoding into the font.
  54.      exch copyfont
  55.      dup /Encoding 4 -1 roll put
  56.        }
  57.        { pop
  58.        }
  59.       ifelse
  60.     }
  61.    if
  62.  } bdef
  63.  
  64. % Insert modified metrics into a font if needed.
  65. /adjustmetrics        % <font-resource> <font> adjustmetrics
  66.             %   <font-resource> <font'>
  67.  { 1 index /Widths known
  68.     { copyfont begin
  69.         % Changing the Metrics invalidates the cache.
  70.         % Remove the UniqueID to ensure this.
  71.       currentdict /UniqueID undef
  72.         % Note that widths are always based on a 1000-unit
  73.         % character space, but the FontMatrix may specify
  74.         % some other scale factor.  Compensate for this here,
  75.         % by scaling the Widths if necessary.
  76.       0.001 /FontMatrix load 0 get div
  77.       /Metrics Encoding length dict def
  78.         % Stack: font-res mscale
  79.       1 index /FirstChar oget dup 1 4 index /LastChar oget
  80.        {    % Stack: font-res mscale first-char index
  81.      Encoding 1 index get
  82.      4 index /Widths oget 2 index 4 index sub get
  83.          % Stack: font-res mscale first-char index charname width
  84.      4 index mul
  85.         % There is a hack here to deal with encodings where the
  86.         % same character appears more than once, because the Metrics
  87.         % dictionary works by character name, not by character code.
  88.         % Because of this, we can't deal with Width vectors that
  89.         % specify different widths for the same character name
  90.         % appearing multiple times in the Encoding.
  91.      Metrics 2 index .knownget not { 0 } if 0 ne
  92.       { pop pop }
  93.       { Metrics 3 1 roll put }
  94.      ifelse pop
  95.        }
  96.       for pop
  97.         % Now fill in the MissingWidth for any encoded characters
  98.         % that aren't in Metrics already.
  99.         % Stack: font-res mscale
  100.       Metrics 2 index /FontDescriptor oget
  101.       /MissingWidth knownoget { 2 index mul } { 0 } ifelse exch
  102.       Encoding
  103.        {    % Stack: font-res mscale missing-width metrics charname
  104.      2 copy known not { 2 copy 4 index put } if pop
  105.        }
  106.       forall pop pop pop
  107.       currentdict end
  108.     }
  109.    if
  110.  } bdef
  111.  
  112. % ---------------- Descriptors ---------------- %
  113.  
  114. % Partial descriptors for the 14 built-in fonts.
  115. /standardfontdescriptors mark
  116.   /Courier mark /Flags 16#23 .dicttomark
  117.   /Courier-Oblique 1 index
  118.   /Courier-Bold 1 index
  119.   /Courier-BoldOblique 1 index
  120.   /Helvetica mark /Flags 16#20 .dicttomark
  121.   /Helvetica-Oblique 1 index
  122.   /Helvetica-Bold 1 index
  123.   /Helvetica-BoldOblique 1 index
  124.   /Times-Roman mark /Flags 16#22 .dicttomark
  125.   /Times-Bold 1 index
  126.   /Times-Italic mark /Flags 16#62 .dicttomark
  127.   /Times-BoldItalic 1 index
  128.   /Symbol mark /Flags 16#4 .dicttomark
  129.   /ZapfDingbats 1 index
  130. .dicttomark readonly def
  131.  
  132. % ---------------- Utilities ---------------- %
  133.  
  134. % Fabricate a font name by adding %'s on the end.
  135. /genfontname        % <name> genfontname <name>
  136.  { dup length string cvs
  137.     { (%) concatstrings
  138.       dup cvn FontDirectory exch known not { cvn exit } if
  139.     }
  140.    loop
  141.  } bdef
  142.  
  143. % Copy a font if needed.  We can recognize a copied font by
  144. % the absence of FID.
  145. /copyfont        % <font> copyfont <font'>
  146.  { dup /FID known
  147.     { dup length dict copy
  148.       dup /FID undef
  149.       dup /FontName 2 copy get genfontname put
  150.     }
  151.    if
  152.  } bdef
  153.  
  154. % Define a modified (copied) font if needed.
  155. /defmodfont        % <font> defmodfont <font'>
  156.  { dup /FID known not { dup /FontName get exch definefont } if
  157.  } bdef
  158.  
  159. % Find a font, and adjust its encoding if necessary.
  160. /pdffindfont        % <font-resource> <fontname> pdffindfont <font>
  161.  { findfont adjustencoding adjustmetrics exch pop defmodfont
  162.  } bdef
  163.  
  164. % ---------------- Type 1 fonts ---------------- %
  165.  
  166. /buildType1        % <Type1-font-resource> buildType1 <font>
  167.  { dup /BaseFont get pdffindfont
  168.  } bdef
  169.  
  170. % The state dictionary for the embedded Type 1 font reading procedure
  171. % has the following keys and values:
  172. %    data - stream (filter)
  173. %    buffer, buffer2 - string
  174. %    leftstr - string containing (non-negative) integer
  175. %    sectionstr - string containing a character 0 .. 2
  176. %    stream - (stream) dictionary
  177. %    proc - procedure of the form {-dict- type1read}
  178. % When the procedure is executing, this dictionary is current.
  179. % leftstr and sectionstr are strings so that we can change their values
  180. % reliably in case the font executes a restore!
  181.  
  182. % Read an embedded Type 1 font.
  183. /readfontfilter        % <proc> readfontfilter <filter>
  184.  {    % We make this a separate procedure so that we can
  185.     % redefine it when we're writing PostScript.
  186.    0 () /SubFileDecode filter
  187.  } bdef
  188. /readtype1        % <font-resource> <stream-dict> readtype1 <font>
  189.  {        % Read the definition, using a procedure-based filter
  190.         % that turns binary/hex conversion on and off
  191.         % at the right times.
  192.    PDFfile fileposition 3 1 roll
  193.    7 dict begin
  194.      /leftstr (          ) 10 string copy def
  195.        dup /Length1 oget leftstr cvs pop
  196.      /sectionstr <00> 1 string copy def
  197.      /stream 1 index def
  198.      true resolvestream /data exch def
  199.      /buffer 200 string def        % arbitrary
  200.      /buffer2 buffer length 2.1 div cvi 1 sub string def
  201.    currentdict end
  202.    /type1read cvx 2 array astore cvx dup 0 get /proc 2 index put
  203.    readfontfilter
  204.         % Some buggy embedded fonts leave extra junk on the stack,
  205.         % so we have to make a closure that records the stack depth
  206.         % in a fail-safe way.
  207.    systemdict begin
  208.     { run } aload pop count 1 sub 2 packedarray cvx exec
  209.    end
  210.    count exch sub { pop } repeat
  211.    PDFfile 3 -1 roll setfileposition
  212.    /FontDescriptor oget /FontName oget findfont
  213.  } bdef
  214.  
  215. % Execute the appropriate reading procedure.
  216. /type1read        % <dict> type1read <string>
  217.  { begin leftstr cvi
  218.     { type1read1 type1read2 type1read3 } sectionstr 0 get get exec
  219.    (          ) leftstr copy cvs pop end
  220.  } bdef
  221.  
  222. % Read the next block of data into the buffer.
  223. /type1readdata        % <left> <buffer> type1readdata <substring> <left'>
  224.  { 0 2 index 2 index length min getinterval
  225.    data exch readstring pop
  226.    dup length 3 -1 roll exch sub
  227.    DEBUG
  228.     { dup =only ( read ) print
  229.       1 index length =only (: ) print
  230.       1 index == flush
  231.     } if
  232.  } bdef
  233.  
  234. % Read the next block of the initial text portion.
  235. /type1read1        % <left> type1read1 <string> <left'>
  236.  { DEBUG { (read1 ) print } if
  237.    dup 0 eq
  238.     { pop sectionstr 0 1 put
  239.       stream /Length2 oget type1read2
  240.     }
  241.     { buffer type1readdata
  242.     }
  243.    ifelse
  244.  } bdef
  245.  
  246. % Read the next block of the encrypted portion.
  247. /type1trailer
  248. (0000000000000000000000000000000000000000000000000000000000000000\n\
  249. 0000000000000000000000000000000000000000000000000000000000000000\n\
  250. 0000000000000000000000000000000000000000000000000000000000000000\n\
  251. 0000000000000000000000000000000000000000000000000000000000000000\n\
  252. 0000000000000000000000000000000000000000000000000000000000000000\n\
  253. 0000000000000000000000000000000000000000000000000000000000000000\n\
  254. 0000000000000000000000000000000000000000000000000000000000000000\n\
  255. 0000000000000000000000000000000000000000000000000000000000000000\n\
  256. cleartomark\n)
  257. readonly def
  258. /type1read2        % <left> type1read2 <string> <left'>
  259.  { DEBUG { (read2 ) print } if
  260.    dup 0 eq
  261.     { pop sectionstr 0 2 put
  262.       stream /Length3 oget
  263.       dup 0 eq
  264.        { DEBUG { (trailer ) print } if
  265.      type1trailer exch
  266.        }
  267.        { type1read3
  268.        }
  269.       ifelse
  270.     }
  271.     { buffer2 type1readdata exch
  272.       buffer /ASCIIHexEncode filter dup 3 -1 roll writestring closefile
  273.       buffer (>) search pop exch pop exch pop exch
  274.     }
  275.    ifelse
  276.  } bdef
  277.  
  278. % Read the next block of the final text portion.
  279. % When finished, this procedure returns an empty string.
  280. /type1read3        % <left> type1read3 <string> <left'>
  281.  { DEBUG { (read3 ) print } if
  282.    buffer type1readdata
  283.  } bdef
  284.  
  285. % ---------------- Type 3 fonts ---------------- %
  286.  
  287. /.notdefEncoding 256 { /.notdef } repeat 256 packedarray def
  288.  
  289. /buildType3        % <Type3-font-resource> buildType3 <font>
  290.   { 8 dict begin
  291.     /FontType 3 def
  292.     /FontBBox 1 index /FontBBox get cvx def
  293.     /FontMatrix 1 index /FontMatrix oget def
  294.     /CharProcs 1 index /CharProcs oget def
  295.     /FontName 1 index /Name get genfontname def
  296.     /Encoding .notdefEncoding 2 index getencoding def
  297.     /BuildGlyph
  298.      { exch /CharProcs get exch oget
  299.        PDFfile fileposition exch
  300.        false resolvestream
  301.         % Don't let setgcolor set the color inside the BuildGlyph
  302.         % procedure, because this causes an /undefined error
  303.        q_ null /FillColor gput null /StrokeColor gput
  304.        pdfopdict .pdfrun
  305.        Q_
  306.        PDFfile exch setfileposition
  307.      } bdef
  308.     FontName currentdict end definefont exch pop
  309.   } bdef
  310.  
  311. % ---------------- TrueType fonts ---------------- %
  312.  
  313. /TTfonts mark
  314.   /Arial /Helvetica
  315.   /Arial,Italic /Helvetica-Oblique
  316.   /Arial,Bold /Helvetica-Bold
  317.   /Arial,BoldItalic /Helvetica-BoldOblique
  318.   /TimesNewRoman /Times-Roman
  319.   /TimesNewRoman,Italic /Times-Italic
  320.   /TimesNewRoman,Bold /Times-Bold
  321.   /TimesNewRoman,BoldItalic /Times-BoldItalic
  322. .dicttomark readonly def
  323.  
  324. /buildTrueType        % <TrueType-font-resource> buildTrueType <font>
  325.  { dup /BaseFont get
  326.    dup TTfonts exch .knownget { exch pop } if pdffindfont
  327.  } bdef
  328.  
  329. % ---------------- Font lookup ---------------- %
  330.  
  331. /fonttypeprocs mark        % <font-resource> -proc- <font>
  332.   /Type1 /buildType1 cvx
  333.   /MMType1 1 index
  334.   /Type3 /buildType3 cvx
  335.   /TrueType /buildTrueType cvx
  336. .dicttomark readonly def
  337.  
  338. /resourcefont            % <font-resource> resourcefont <font>
  339.  { dup /PSFont .knownget
  340.     { /FID .knownget
  341.        { type /fonttype eq }
  342.        { false }
  343.       ifelse
  344.     }
  345.     { false
  346.     }
  347.    ifelse
  348.     { /PSFont get
  349.     }
  350.     { dup dup /FontDescriptor knownoget
  351.        { /FontFile knownoget }
  352.        { false }
  353.       ifelse
  354.        { 1 index 3 1 roll readtype1 adjustencoding adjustmetrics exch pop defmodfont }
  355.        { dup /Subtype get fonttypeprocs exch get exec }
  356.       ifelse
  357.       2 copy /PSFont exch put
  358.       exch pop
  359.     }
  360.    ifelse
  361.  } bdef
  362.  
  363. drawopdict begin
  364.   /d0 /setcharwidth load def
  365.   /d1 /setcachedevice load def
  366.   /Tf
  367.    { exch Page /Resources oget /Font oget exch oget resourcefont
  368.      exch Tf
  369.    } bdef
  370. end
  371.  
  372. end            % pdfdict
  373. end            % GS_PDF_ProcSet
  374. .setglobal
  375.